Skip to content

Fix inline export forwarder generation regression #23126

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

jchyb
Copy link
Contributor

@jchyb jchyb commented May 8, 2025

To explain what was happening and what the issue was:
Minimalisation:

import scala.quoted.*

package jam {
  trait JamCoreDsl {
    implicit inline def defaultJamConfig: this.JamConfig =
      new JamConfig(brewRecRegex = ".*")
    class JamConfig(val brewRecRegex: String)
    inline def brew(implicit inline config: JamConfig): Unit = ???
  }
  private object internal extends JamCoreDsl
  export internal._
}

object test {
  jam.brew
}

would fail retyping in the inlining phase.

During typer, because we were exporting contents of Internal, the compiler created forwarders (in Namer.addForwarder) for methods chosen in the export. The forwarders looked like this:

      final implicit inline def defaultJamConfig: jam.internal.JamConfig =
        jam.Internal.defaultJamConfig
      final inline def brew(implicit inline config: jam.internal.JamConfig):
        Unit = jam.Internal.brew(config)

While creating them, the compiler would also try to type them. Because those forwarder methods were inline, the compiler would call PrepareInlineable.makeInlineable on them. That method would transform rhs of the forwarder method, to make sure it does not reference any private methods/objects. Since Internal is private (and referenced in both exported methods, notably in brew with rhs jam.Internal.brew(config)), an accessor inline$Internal was created, and the forwarder method contents remapped.

Then, during inlining in the inline phase, the ReTyper was not able to type jam.inline$internal.brew(config), with jam.inline$internal.brew being typed as Nothing => Unit (likely having remapped the argument to Nothing in an asSeenFrom, after deciding that the prefix is not stable).

But none of this happened when I created those forwarders and accessors manually. After some digging it turned out that the inline$internal accessor method was typed as TypeRef(ThisType(TypeRef(NoPrefix,module class jam)),module class internal$)), but the manually created one was a TermRef(ThisType(TypeRef(NoPrefix,module class jam)), object Internal). It seems like the first one has an unstable prefix, so its denotation is not typed correctly, leading to the issue.
Fixes #22593

@jchyb jchyb force-pushed the fix-i22593-export-inline-regression branch 2 times, most recently from 5cd4b5f to 4f1194d Compare May 14, 2025 16:50
@jchyb jchyb marked this pull request as ready for review May 14, 2025 16:52
@jchyb jchyb changed the title WIP: fix inline export forwarder generation regression Fix inline export forwarder generation regression May 14, 2025
@jchyb jchyb force-pushed the fix-i22593-export-inline-regression branch from 4f1194d to 5e8eee3 Compare May 15, 2025 09:26
@jchyb jchyb requested a review from hamzaremmal May 15, 2025 09:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Regression in yakivy/jam - unknown value error in separate compilation runs
2 participants